package com.credithc.signature.manager.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.credithc.signature.common.constant.ResponseEnum;
import com.credithc.signature.common.mapper.ChannelMapper;
import com.credithc.signature.common.mapper.DatapushMapper;
import com.credithc.signature.common.mapper.TemplateMapper;
import com.credithc.signature.common.po.Channel;
import com.credithc.signature.common.po.DatapushChannel;
import com.credithc.signature.common.po.DatapushTemplate;
import com.credithc.signature.common.po.Template;
import com.credithc.signature.common.to.DataPushResult;
import com.credithc.signature.common.utils.DateUtil;
import com.credithc.signature.manager.constant.DateConstant;
import com.credithc.signature.manager.ro.DataPushRo;
import com.credithc.signature.manager.service.DataPushApiServie;
import com.credithc.signature.manager.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @desc: <br/>
 * @author: Jingbo Hu<br/>
 * @time：2020年05⽉19⽇<br/>
 * @version：v1.0.0<br>
 */
@Service
@Slf4j
public class DataPushApiServieImpl implements DataPushApiServie {


    @Autowired
    DatapushMapper datapushMapper;

    @Autowired
    ChannelMapper channelMapper;

    @Autowired
    TemplateMapper templateMapper;


    @Override
    public DataPushResult verifyRequestBody(DataPushRo dataPushRo) {
        if (StringUtils.isEmpty(dataPushRo.getProductCode())) {
            return new DataPushResult(false, "渠道编号不能为空");
        }
        if (StringUtils.isEmpty(dataPushRo.getCycle())) {
            return new DataPushResult(false, "查询时间范围不能为空");
        }
        return new DataPushResult(true, "验证成功");
    }


    @Override
    public Object listDataInfos(DataPushRo dataPushRo) {
        String cycle = dataPushRo.getCycle();
        if (DateConstant.WEEK.equals(cycle)) {
            // 按周统计
            LocalDate today = LocalDate.now();
            LocalDate todayOfLastWeek = today.minusDays(7);
            LocalDate monday = todayOfLastWeek.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1);
            LocalDate sunday = todayOfLastWeek.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).minusDays(1);
            log.info("当前日期：" + today + " 上一周的周一：" + monday + " " + monday.getDayOfWeek());
            log.info("当前日期：" + today + " 上一周的周日：" + sunday + " " + sunday.getDayOfWeek());
            JSONObject data = listDataInfosWithCondition(dataPushRo, monday, sunday);
            return ResponseUtil.getResponseMessageData(ResponseEnum.COUNT_SUCCESS.getCode(), data);
        } else if (DateConstant.MONTH.equals(cycle)) {
            // 按月统计
            LocalDate today = LocalDate.now();
            LocalDate lastMonthToday = today.minusMonths(1);
            LocalDate firstDay = lastMonthToday.with(TemporalAdjusters.firstDayOfMonth());
            LocalDate lastDay = lastMonthToday.with(TemporalAdjusters.lastDayOfMonth());
            log.info("当前日期：" + today + " 上个月第一天：" + firstDay);
            log.info("当前日期：" + today + " 上个月最后一天：" + lastDay);
            JSONObject data = listDataInfosWithCondition(dataPushRo, firstDay, lastDay);
            return ResponseUtil.getResponseMessageData(ResponseEnum.COUNT_SUCCESS.getCode(), data);
        } else if (DateConstant.DAY.equals(cycle)) {
            // 按日统计
            LocalDate today = LocalDate.now();
            LocalDate yesterdayDate = today.minusDays(1);
            log.info("当前日期：" + today + " 昨天日期：" + yesterdayDate);
            JSONObject data = listDataInfosWithCondition(dataPushRo, yesterdayDate, null);
            return ResponseUtil.getResponseMessageData(ResponseEnum.COUNT_SUCCESS.getCode(), data);
        } else {
            // 全部数据
            List<DatapushChannel> dataPushChannels = datapushMapper.listAllDataInfos();
            List<DatapushTemplate> dataPushTemplates = datapushMapper.listTop20DataInfoS();
            JSONObject data = buildJsonData(dataPushRo, dataPushChannels, dataPushTemplates);
            return ResponseUtil.getResponseMessageData(ResponseEnum.COUNT_SUCCESS.getCode(), data);
        }
    }

    /**
     * 封装返回信息
     *
     * @param dataPushRo
     * @param dataPushChannels
     * @param dataPushTemplates
     * @return
     */
    private JSONObject buildJsonData(DataPushRo dataPushRo, List<DatapushChannel> dataPushChannels, List<DatapushTemplate> dataPushTemplates) {
        JSONObject data = new JSONObject();
        JSONArray array = new JSONArray();
        data.put("productCode", dataPushRo.getProductCode());
        // 构建系统统计信息
        JSONObject channel = new JSONObject();
        channel.put("tableKey", "channelType");
        channel.put("tableName", "系统统计");
        channel.put("columns", "系统名称,统计日期,总签约量,成功数,失败数");
        List<List<Object>> channelList = new ArrayList<>();
        dataPushChannels.forEach(d -> {
            String channelName = d.getChannelName();
            Date countDate = d.getCountDate();
            Integer total = d.getTotal();
            Integer success = d.getSuccess();
            Integer fail = d.getFail();
            List<Object> objectList = new ArrayList<>();
            objectList.add(channelName);
            objectList.add(DateUtil.getDefaultAppointDateStr2(countDate));
            objectList.add(total.toString());
            objectList.add(success.toString());
            objectList.add(fail.toString());
            channelList.add(objectList);
        });
        channel.put("list", channelList);
        array.add(channel);

        // 构建模板统计信息
        JSONObject template = new JSONObject();
        template.put("tableKey", "templateType");
        template.put("tableName", "模板统计");
        template.put("columns", "模板编号,统计日期,总签约量,成功数,失败数");
        List<List<Object>> templateList = new ArrayList<>();
        dataPushTemplates.forEach(d -> {
            String templateNo = d.getTemplateNo();
            Date countDate = d.getCountDate();
            Integer total = d.getTotal();
            Integer success = d.getSuccess();
            Integer fail = d.getFail();
            List<Object> objectList = new ArrayList<>();
            objectList.add(templateNo);
            objectList.add(DateUtil.getDefaultAppointDateStr2(countDate));
            objectList.add(total.toString());
            objectList.add(success.toString());
            objectList.add(fail.toString());
            templateList.add(objectList);
        });
        template.put("list", templateList);
        array.add(template);
        data.put("tables", array);
        return data;
    }

    /**
     * 按照条件统计数据
     *
     * @param dataPushRo
     * @param dateFrom
     * @param dateTo
     * @return
     */
    private JSONObject listDataInfosWithCondition(DataPushRo dataPushRo, LocalDate dateFrom, LocalDate dateTo) {
        String startTime = dateFrom.toString();
        String endTime = null;
        if (dateTo != null) {
            endTime = dateTo.toString();
        }
        Channel channel = channelMapper.selectByChannelNo(dataPushRo.getProductCode());
        // 过滤系统数据
        List<DatapushChannel> dataPushChannels = datapushMapper.listStatisticsInfosByDate(startTime, endTime);
        dataPushChannels = dataPushChannels.stream().filter(d -> channel.getChannelNo().equals(d.getChannelNo()) || channel.getChannelMappingNo().equals(d.getChannelNo())).collect(Collectors.toList());
        Map<Date, List<DatapushChannel>> collect = dataPushChannels.stream().collect(Collectors.groupingBy(DatapushChannel::getCountDate));
        Iterator<Map.Entry<Date, List<DatapushChannel>>> iterator = collect.entrySet().iterator();
        dataPushChannels = new ArrayList<>();
        while (iterator.hasNext()) {
            Map.Entry<Date, List<DatapushChannel>> next = iterator.next();
            Date countDate = next.getKey();
            List<DatapushChannel> value = next.getValue();
            int total = value.stream().mapToInt(DatapushChannel::getTotal).sum();
            int success = value.stream().mapToInt(DatapushChannel::getSuccess).sum();
            int fail = value.stream().mapToInt(DatapushChannel::getFail).sum();
            DatapushChannel datapushChannel = new DatapushChannel();
            datapushChannel.setChannelNo(channel.getChannelNo());
            datapushChannel.setChannelName(channel.getChannelName());
            datapushChannel.setCountDate(countDate);
            datapushChannel.setTotal(total);
            datapushChannel.setSuccess(success);
            datapushChannel.setFail(fail);
            dataPushChannels.add(datapushChannel);
        }
        dataPushChannels = dataPushChannels.stream().sorted(Comparator.comparing(DatapushChannel::getCountDate)).collect(Collectors.toList());

        // 过滤模板数据
        List<DatapushTemplate> dataPushTemplates = datapushMapper.listStatisticsInfosByDate2(startTime, endTime);
        List<String> templateNos = templateMapper.selectByChannelId(channel.getId()).stream().map(Template::getTemplateNo).collect(Collectors.toList());
        List<DatapushTemplate> dataPushTemplatesNew = new ArrayList<>();
        dataPushTemplates.forEach(s -> {
            boolean contains = templateNos.contains(s.getTemplateNo());
            if (contains) {
                dataPushTemplatesNew.add(s);
            }
        });
        return buildJsonData(dataPushRo, dataPushChannels, dataPushTemplatesNew);
    }
}
